// ES5 类的创建
// function Person(name, age) {
//   // 构造函数
//   this.name = name
//   this.age = age
// }
// Person.prototype.sayHi = function () {
//   // 原型
//   console.log("Hi", this.name)
// }

// Person.country = "China" // 静态属性

// // 寄生组合式继承
// function Student(name, age, grade) {
//   this.grade = grade
//   Person.apply(this, arguments)
// }

// function inheritPrototype(Student, Person) {
//   function F() {}

//   F.prototype = Person.prototype
//   Student.prototype = new F()
//   Student.prototype.constructor = Student
// }

// inheritPrototype(Student, Person)

// ES6 类的创建
class Person {
  constructor(name, age) {
    // 构造函数
    this.name = name
    this.age = age
  }
  sayHi() {
    // 放在原型上的
    console.log("Hi", this.name)
  }
}

//  实例化
let p1 = new Person("lucy", 18)
p1.sayHi()
console.dir(p1)

// ES6 继承
class Student extends Person {
  city = "成都" // ES7 语法，等价于写在 constructor 中的
  constructor(name, age, grade) {
    super(name, age) // 必须在子类的 constructor 中先调用 super 实现继承
    this.grade = grade
  }
  static country = "China" // 静态属性
  static run() {
    // 静态方法
    console.log("run")
  }

  get sex() {
    // 获取 sex 属性的时候会触发该函数
    console.log("获取性别")
    return "女"
  }
  set sex(newVal) {
    // 设置该属性的时候会触发该函数
    console.log("设置 sex", newVal)
  }
}

// 实例化子类
let s1 = new Student("lily", 18, "高三")
s1.sayHi()
console.dir(s1)

console.log(Student.country)
Student.run()

console.log(s1.sex)

s1.sex = "男"

// 涵盖 class 的构造函数、原型、静态属性、以及最新写法
class Cat {
  // 静态
  static instance = null

  // 以下举几个写法都是实例的属性
  city = "成都"

  constructor(name) {
    this.name = name
  }
  sayBye = function () {
    console.log("Bye")
  }
  run = () => {
    console.log("run")
  }

  say() {
    // 原型上的方法
    console.log("喵喵")
  }
}

const c = new Cat("花花")
console.dir(c)
